
#include <stdio.h>
#include <string.h>
#include <hardware/dtv.h>

int main(int argc,char *argv[])
{
	int r=0;
	dtv_module_t* module;
	
	r=hw_get_module(DTV_HARDWARE_MODULE_ID, (const hw_module_t**)&module);
	if(r<0)
	{
		printf("hw_get_module error\n");
		return -1;
	}

	r=module->init(module);
	if(r<0)
	{
		printf("init error\n");
		return -1;
	}

	tuner_device_t *tuner;
	r=dtv_device_tuner_open((const hw_module_t*)module,&tuner);
	if(r<0)
	{
		printf("dtv_device_tuner_open error\n");
		return -1;
	}

	tuner_param_t param;
	param.type=TUNER_TYPE_DVBC;
	param.dvbc.frequency=666000;
	param.dvbc.symbol_rate=6875000;
	param.dvbc.qam=TUNER_QAM_MODE_64QAM;
	param.dvbc.spectrum=TUNER_SPECTRUM_MODE_AUTO;
	r=tuner->set_parameter(tuner,0,&param);
	if(r<0)
	{
		printf("tuner->set_parameter error\n");
		return -1;
	}

	tuner_status_t status;
	for(int i=0;i<20;i++)
	{
		r=tuner->get_status(tuner,0,&status);
		if(r<0)
		{
			printf("tuner->get_status error\n");
			return -1;
		}
		if(status.locked)
		{
			printf("try %d times\n",i+1);
			break;
		}
	}

	printf("status.locked=%d\n",status.locked);
	printf("status.strength=%d\n",status.strength);
	printf("status.qulity=%d\n",status.qulity);
	printf("status.power=%d\n",status.power);
	printf("status.snr=%d\n",status.snr);
	printf("status.ber=%d\n",status.ber);
	printf("status.param.dvbc.frequency=%d\n",status.param.dvbc.frequency);
	printf("status.param.dvbc.symbol_rate=%d\n",status.param.dvbc.symbol_rate);
	printf("status.param.dvbc.qam=%d\n",status.param.dvbc.qam);
	printf("status.param.dvbc.spectrum=%d\n",status.param.dvbc.spectrum);

	demux_device_t *demux;
	r=dtv_device_demux_open((const hw_module_t*)module,&demux);
	if(r<0)
	{
		printf("dtv_device_demux_open error\n");
		return -1;
	}

	r=demux->link_tuner(demux,0,0);
	if(r<0)
	{
		printf("link_tuner error\n");
		return -1;
	}

	int channel;
	r=demux->create_channel(demux,0,
		DEMUX_CHANNEL_TYPE_SECTION,
		DEMUX_CHANNEL_CRC_ENABLE,
		1024*16,&channel);
	if(r<0)
	{
		printf("create_channel error\n");
		return -1;
	}

	r=demux->set_channel_pid(demux,channel,0);
	if(r<0)
	{
		printf("set_channel_pid error\n");
		return -1;
	}

	int filter;
	demux_filter_param_t fparam;
	fparam.depth=1;
	fparam.match[0]=0;
	fparam.mask[0]=0xFF;
	fparam.negate[0]=0;
	r=demux->create_filter(demux,0,&fparam,&filter);
	if(r<0)
	{
		printf("create_filter error\n");
		return -1;
	}

	r=demux->start_channel(demux,channel);
	if(r<0)
	{
		printf("start_channel error\n");
		return -1;
	}

	r=demux->associate_filter(demux,filter,channel);
	if(r<0)
	{
		printf("associate_filter error\n");
		return -1;
	}

	int wchn;
	int acount=0;
	r=demux->wait_channel(demux,&wchn,1,2000,&acount);
	if(r<0)
	{
		printf("wait_channel error\n");
		return -1;
	}

	printf("channel=0x%08X   wchn=0x%08X   acount=%d\n",
		channel,wchn,acount);

	static unsigned char buf[4096];
	int size=0;
	r=demux->read_channel(demux,channel,buf,4096,NULL,0,&size);
	if(r<0)
	{
		printf("read_channel error\n");
		return -1;
	}

	printf("Section Received[%d]:\n",size);
	for(int i=0;i<size;i++)
	{
		printf("%02X ",buf[i]);
		if((i+1)%16==0)printf("\n");
	}
	printf("\n");

	r=demux->stop_channel(demux,channel);
	if(r<0)
	{
		printf("stop_channel error\n");
		return -1;
	}

	r=demux->disassociate_filter(demux,filter,channel);
	if(r<0)
	{
		printf("disassociate_filter error\n");
		return -1;
	}

	r=demux->destroy_filter(demux,filter);
	if(r<0)
	{
		printf("destroy_filter error\n");
		return -1;
	}
	
	r=demux->destroy_channel(demux,channel);
	if(r<0)
	{
		printf("destroy_channel error\n");
		return -1;
	}
	
	r=demux->unlink_tuner(demux,0);
	if(r<0)
	{
		printf("unlink_tuner error\n");
		return -1;
	}

	r=dtv_device_demux_close(demux);
	if(r<0)
	{
		printf("dtv_device_demux_close error\n");
		return -1;
	}

	r=dtv_device_tuner_close(tuner);
	if(r<0)
	{
		printf("dtv_device_tuner_close error\n");
		return -1;
	}

	r=module->deinit(module);
	if(r<0)
	{
		printf("deinit error\n");
		return -1;
	}
	
	printf("Test Pass.\n");
	return 0;
}



